package clock.socoolby.com.clock;


import android.annotation.SuppressLint;
import android.annotation.TargetApi;

import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;

import android.content.Intent;
import android.graphics.Point;
import android.net.Uri;
import android.os.Build;
import android.os.PowerManager;
import android.os.Bundle;
import android.provider.Settings;
import androidx.core.app.ActivityCompat;
import androidx.appcompat.app.AppCompatActivity;
import android.view.Display;
import android.view.GestureDetector;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.Toast;

import com.badlogic.gdx.backends.androidx.AndroidFragmentApplication;
import com.blankj.utilcode.util.PermissionUtils;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import com.luck.picture.lib.PictureSelector;
import com.luck.picture.lib.config.PictureConfig;
import com.luck.picture.lib.config.PictureMimeType;
import com.luck.picture.lib.entity.LocalMedia;

import java.text.NumberFormat;
import java.util.List;

import clock.socoolby.com.clock.alter.AlterManager;
import clock.socoolby.com.clock.dao.base.TimeFontStyle;
import clock.socoolby.com.clock.event.EventManger;
import clock.socoolby.com.clock.fragment.alter.AbstractAlterFragment;
import clock.socoolby.com.clock.fragment.alter.AlterTodoDefaultFragment;
import clock.socoolby.com.clock.fragment.system.SystemAppConfigFragment;
import clock.socoolby.com.clock.fragment.handup.AbstractHandUpFragment;
import clock.socoolby.com.clock.fragment.handup.HandUpFragmentFactory;
import clock.socoolby.com.clock.fragment.digit.DigitClockConfigFragment;
import clock.socoolby.com.clock.fragment.digit.DigitClockFragment;
import clock.socoolby.com.clock.fragment.houranimator.HourAnimatorFactory;
import clock.socoolby.com.clock.fragment.simulate.SimulateClockConfigFragment;
import clock.socoolby.com.clock.fragment.simulate.SimulateClockFragment;
import clock.socoolby.com.clock.fragment.theme.ThemeUIDefaultFragment;
import clock.socoolby.com.clock.fragment.theme.ThemeUISampleFragment;
import clock.socoolby.com.clock.net.BusinessService;
import clock.socoolby.com.clock.net.listener.RequestListener;
import clock.socoolby.com.clock.net.protocol.weather.WeatherResponse;
import clock.socoolby.com.clock.service.ProximityService;
import clock.socoolby.com.clock.state.ClockModeEnum;
import clock.socoolby.com.clock.state.ClockStateMachine;
import clock.socoolby.com.clock.model.SharePerferenceModel;
import clock.socoolby.com.clock.state.ClockInterfaceTypeEnum;
import clock.socoolby.com.clock.state.ClockThemeUITypeEnum;
import clock.socoolby.com.clock.todo.TodoSyncServiceManager;
import clock.socoolby.com.clock.utils.DialogUtils;
import clock.socoolby.com.clock.viewmodel.AlterViewModel;
import clock.socoolby.com.clock.viewmodel.DigitViewModel;
import clock.socoolby.com.clock.viewmodel.GlobalViewModel;
import clock.socoolby.com.clock.viewmodel.SimulateViewModel;
import clock.socoolby.com.clock.viewmodel.ThemeUIViewModel;
import clock.socoolby.com.clock.viewmodel.ViewModelFactory;
import clock.socoolby.com.clock.widget.animatorview.AnimatorView;
import clock.socoolby.com.clock.widget.animatorview.I_Animator;
import clock.socoolby.com.clock.widget.animatorview.animator.FishAnimator;
import clock.socoolby.com.clock.widget.animatorview.animator.clockanimator.ClockFactory;

import static clock.socoolby.com.clock.state.ClockThemeUITypeEnum.FULLSCREEN;
import static clock.socoolby.com.clock.state.ClockThemeUITypeEnum.SETTING;


public class MainActivity extends AppCompatActivity implements  android.view.GestureDetector.OnGestureListener, ScaleGestureDetector.OnScaleGestureListener, GestureDetector.OnDoubleTapListener, AndroidFragmentApplication.Callbacks {
    private final static String TAG = MainActivity.class.getSimpleName();

    //背景动画
    private AnimatorView animatorView;

    private I_Animator backGroundAnimator;

    private final static int ANIMATOR_TEXTLED = 80;

    private FrameLayout themeUIContainer;

    //背景图相关
    private ImageView tv_background_image;

    // 定义手势检测器实例
    GestureDetector detector;
    ScaleGestureDetector scaleGestureDetector;

    private PowerManager.WakeLock wakeLock = null;

    private SharePerferenceModel model;

    public WeatherResponse weatherAdape;

    private ClockStateMachine clockStateMachine;

    Intent proximityServiceIntent = null;
    FontManager fontManager;

    GlobalViewModel globalViewModel;
    DigitViewModel digitViewModel;
    SimulateViewModel simulateViewModel;
    ThemeUIViewModel themeUIViewModel;
    AlterViewModel alterViewModel;

    private AlterManager alterManager;

    private ThemeUIManager themeUIManager;

    private AnimatorManager animatorManager;

    private SpiritsManager spiritsManager;

    private BusinessService businessService;

    private TodoSyncServiceManager todoSyncServiceManager;

    @SuppressLint("InvalidWakeLockTag")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        model = ((ClockApplication) getApplication()).getModel();

        themeUIContainer = findViewById(R.id.main_background);
        tv_background_image = findViewById(R.id.tv_background_image);

        animatorView = findViewById(R.id.tv_background_animatorview);

        if (PermissionUtils.isGranted("android.permission.WAKE_LOCK", "android.permission.DEVICE_POWER")) {
            PowerManager powerManager = (PowerManager) this.getSystemService(POWER_SERVICE);
            wakeLock = powerManager.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.FULL_WAKE_LOCK | powerManager.ON_AFTER_RELEASE, "Clock");
        } else
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        //创建手势检测器
        detector = new GestureDetector(this, this);
        detector.setOnDoubleTapListener(this);

        scaleGestureDetector = new ScaleGestureDetector(this, this);

        init();

        spiritsManager.initContiner(findViewById(R.id.spirits_container),getSupportFragmentManager(),R.id.fragment_spine_container);

        testSetup();

    }

    private boolean isPowerManagerDisable() {
        return wakeLock == null;
    }


    private void setUpProximityService() {
        if (isPowerManagerDisable()&&Build.VERSION.SDK_INT < Build.VERSION_CODES.P)
            return;
        try {
            if (isScreenLock()) {
                stopService(proximityServiceIntent);
            } else {
                if (model.isTriggerScreen()) {
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                            startForegroundService(proximityServiceIntent);
                    }else
                       startService(proximityServiceIntent);
                } else {
                    stopService(proximityServiceIntent);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    private void onRequestPermissions(int reqCode, String... permissions) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (!PermissionUtils.isGranted(permissions)) {
                ActivityCompat.requestPermissions(this,
                        permissions,
                        reqCode);
            } else {
                Toast.makeText(this, "权限已申请", Toast.LENGTH_LONG).show();
            }
        }
    }

    private void init() {
        businessService= ((ClockApplication) getApplication()).getBusinessService();
        timber.log.Timber.d("start model:" + model.toString());

        proximityServiceIntent = new Intent(this, ProximityService.class);

        fontManager = new FontManager(ClockApplication.getInstance().getEntityManager());

        animatorManager = new AnimatorManager();

        ViewModelFactory viewModelFactory = new ViewModelFactory(model);
        globalViewModel = ViewModelProviders.of(MainActivity.this, viewModelFactory).get(GlobalViewModel.class);
        digitViewModel = ViewModelProviders.of(MainActivity.this, viewModelFactory).get(DigitViewModel.class);
        simulateViewModel = ViewModelProviders.of(MainActivity.this, viewModelFactory).get(SimulateViewModel.class);
        themeUIViewModel = ViewModelProviders.of(MainActivity.this, viewModelFactory).get(ThemeUIViewModel.class);
        alterViewModel = ViewModelProviders.of(MainActivity.this, viewModelFactory).get(AlterViewModel.class);

        alterManager = new AlterManager(model.getStartHourPowerTime(), model.getStopHourPowerTime(), globalViewModel, ClockApplication.getInstance().getEntityManager());

        todoSyncServiceManager = new TodoSyncServiceManager(this.getApplicationContext());
        globalViewModel.setTodoSyncServiceManager(todoSyncServiceManager);

        clockStateMachine = new ClockStateMachine(alterManager, globalViewModel, digitViewModel, simulateViewModel, themeUIViewModel, alterViewModel,todoSyncServiceManager);
        globalViewModel.setClockStateMachine(clockStateMachine);

        themeUIManager = new ThemeUIManager(ClockApplication.getInstance().getEntityManager(), model,fontManager);
        globalViewModel.setThemeUIManager(themeUIManager);

        bindViewModel();

        spiritsManager=new SpiritsManager(globalViewModel,digitViewModel,simulateViewModel,themeUIViewModel,alterViewModel);

    }

    //这里对第一次启动
    private void firstStartSetup(){
        model.setFirstStart(false);
    }


    int daily = 30;

    private void testSetup() {

        //model.setFirstStart(true);

        //model.setBootStart(true);

        //globalViewModel.getHandUpTypeName().setValue(HandUpSelect123Fragment.NAME);

        /*globalViewModel.getHourAlterTypeName().setValue(HourVideoFragment.NAME);
        Observer<Boolean>  timeChange= new Observer<Boolean>() {
            @Override
            public void onChanged(Boolean aBoolean) {
                daily--;
                Log.d("main activity","test hour aninamtor daily:"+daily);
                if(daily==0){
                    Log.d("main activity","test hour aninamtor is start!");
                    globalViewModel.setTimeHourAnimatorStarting(true);
                    globalViewModel.getHeartbeat().removeObserver(this);
                }
            }
        };
        globalViewModel.getHeartbeat().observe(this,timeChange);*/

        /*try {
            themeUIManager.saveDigitTheme("text",model.getDigitPerferenceModel());
        } catch (BasicException e) {
            e.printStackTrace();
        }

        try {
            DigitPerferenceModel digitPerferenceModel= themeUIManager.loadDigitTheme("text");
            System.out.println(digitPerferenceModel.toString());
        } catch (BasicException e) {
            e.printStackTrace();
        }*/

        //fontManager.addCoustomFontStyle(new TimeFontStyle("BONX-TubeBold", 110, 120, 130, 150));
        //fontManager.addCoustomFontStyle(new TimeFontStyle("BONX-TubeBoldReverse", 110, 120, 130, 150));
    }


    private void bindViewModel() {

        globalViewModel.getUseSystemWallpaper().observe(this, new Observer<Boolean>() {
            @Override
            public void onChanged(Boolean aBoolean) {
                if(aBoolean){
                    getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER);
                }else{
                    getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER);
                }
                globalViewModel.checkSystemWallpaperSet();
            }
        });

        globalViewModel.getClockInterfaceTypeEnum().observe(this, new Observer<ClockInterfaceTypeEnum>() {
            @Override
            public void onChanged(ClockInterfaceTypeEnum clockInterfaceTypeEnum) {
                timber.log.Timber.d("comming in clockInterfaceTypeEnum change observe type:"+clockInterfaceTypeEnum.name());
                switch (clockInterfaceTypeEnum) {
                    case Digit:
                        getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new DigitClockFragment()).commit();
                        break;
                    case Simulate:
                        getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new SimulateClockFragment()).commit();
                        break;
                }
                clockStateMachine.setCurrentInterfaceType(clockInterfaceTypeEnum);
            }
        });

        EventManger.addHandupListener(this,event->{
            if(event.getValue()) {
                closeAllConfigFragment();
                AbstractHandUpFragment alterFragment = HandUpFragmentFactory.build(globalViewModel.getHandUpTypeName().getValue(), clockStateMachine);
                getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, alterFragment).addToBackStack(null).commit();
            }else
                getSupportFragmentManager().popBackStack();
          }
        );

        EventManger.addAlterListener(this,event->{
                    if(event.getValue()) {
                        closeAllConfigFragment();
                        AbstractAlterFragment alterFragment = new AlterTodoDefaultFragment();
                        getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, alterFragment).addToBackStack(null).commit();
                    }else
                        getSupportFragmentManager().popBackStack();
                }
        );

        themeUIViewModel.getThemeName().observe(this, new Observer<String>() {
            @Override
            public void onChanged(String s) {
                switch (s) {
                    case ThemeUISampleFragment.THEME_NAME:
                        getSupportFragmentManager().beginTransaction().replace(R.id.fragment_config_container, new ThemeUISampleFragment()).commit();
                        break;
                    default:
                        getSupportFragmentManager().beginTransaction().replace(R.id.fragment_config_container, new ThemeUIDefaultFragment()).commit();
                }
            }
        });

        globalViewModel.getBackgroundImageVisable().observe(this, new Observer<Boolean>() {
            @Override
            public void onChanged(Boolean visible) {
                tv_background_image.setVisibility(visible ? View.VISIBLE : View.GONE);
            }
        });

        globalViewModel.getBackgroundImageUri().observe(this, new Observer<Uri>() {
            @Override
            public void onChanged(Uri uri) {
                if (uri == null) {
                    tv_background_image.setVisibility(View.GONE);
                    return;
                }
                RequestOptions options = new RequestOptions();
                options.centerCrop();
                //tv_background_image.setVisibility(View.VISIBLE);
                Glide.with(MainActivity.this)
                        .load(uri.toString())
                        .apply(options)
                        .into(tv_background_image);
            }
        });

        globalViewModel.getSrceenLock().observe(this, new Observer<Boolean>() {
            @Override
            public void onChanged(Boolean aBoolean) {
                setUpProximityService();
            }
        });

        globalViewModel.getBackgroundColor().observe(this, new Observer<Integer>() {
            @Override
            public void onChanged(Integer integer) {
                setBackGroundColor(integer);
            }
        });

        globalViewModel.getBackgroundAnimatorName().observe(this, new Observer<String>() {
            @Override
            public void onChanged(String s) {
                changeBackGroundAnimator(s, globalViewModel.getBackgroundAnimatorRandomColor());
            }
        });

        globalViewModel.getBackgroundAnimatorColor().observe(this, new Observer<Integer>() {
            @Override
            public void onChanged(Integer integer) {
                changeBackGroudAnimatorColor(integer);
            }
        });

        globalViewModel.getBrightness().observe(this, new Observer<Integer>() {
            @Override
            public void onChanged(Integer integer) {
                changeAppBrightness(integer);
            }
        });

        digitViewModel.getTimeFontName().observe(this, new Observer<String>() {
            @Override
            public void onChanged(String s) {
                fontManager.setCurrentFontName(model.getFontName());
                digitViewModel.getTimeFontStyle().setValue(fontManager.getCurrentFontStyle());
            }
        });

        digitViewModel.getTimeFontStyle().observe(this, new Observer<TimeFontStyle>() {
            @Override
            public void onChanged(TimeFontStyle timeFontStyle) {
                digitViewModel.setTimeFontStyleSize(fontManager.getCurrentFontSize(themeUIViewModel.getClockUITypeEnum().getValue() == FULLSCREEN, model.isDisplaySecond()));
            }
        });

        themeUIViewModel.getClockUITypeEnum().observe(this, new Observer<ClockThemeUITypeEnum>() {
            @Override
            public void onChanged(ClockThemeUITypeEnum clockThemeUITypeEnum) {
                int fontSize = 0;
                boolean displaySecond = model.isDisplaySecond();
                switch (clockThemeUITypeEnum) {
                    case FULLSCREEN:
                        fontSize = fontManager.getCurrentFontSize(true, displaySecond);
                        spiritsManager.setRunning(true);
                        break;
                    default:
                        fontSize = fontManager.getCurrentFontSize(false, displaySecond);
                        spiritsManager.setRunning(false);
                }
                digitViewModel.setTimeFontStyleSize(fontSize);
            }
        });

        digitViewModel.getDisplaySecond().observe(this, new Observer<Boolean>() {
            @Override
            public void onChanged(Boolean aBoolean) {
                digitViewModel.setTimeFontStyleSize(fontManager.getCurrentFontSize(themeUIViewModel.getClockUITypeEnum().getValue() == FULLSCREEN, aBoolean));
            }
        });

        EventManger.addHourAnimatorListener(this,event->{
            timber.log.Timber.d("on hour animator changed: " + event.getValue());
            if (event.getValue())
                getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, HourAnimatorFactory.builder(globalViewModel.getHourAlterTypeName().getValue(), globalViewModel.getTime_hour().getValue())).addToBackStack(null).commit();
            else
                getSupportFragmentManager().popBackStack();
        });

        EventManger.addLongSleepWakeUpListener(this,event -> {
            timber.log.Timber.d("on long sleep wake up: " + event.getValue());
            getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, HourAnimatorFactory.builder(FishAnimator.NAME, event.getValue())).addToBackStack(null).commit();
        });

        EventManger.addNewDayListener(this,event -> {
            timber.log.Timber.d("new day comming: " + event.getValue().getDateString());
            businessService.getWeather(model.getCity(), new RequestListener<WeatherResponse>() {
                @Override
                public void onResponse(WeatherResponse weather) {
                    if (weather == null)
                        return;
                    timber.log.Timber.d("set Weather ...");
                    weatherAdape = weather;
                    if (weather.getTodayWeather() != null)
                        themeUIViewModel.getWeatherDescription().setValue(weather.getTodayWeather().weather + "/" + weather.getTodayWeather().temperature);

                }

                @Override
                public void onRequestFailed(int error, String errorMessage) {
                    timber.log.Timber.d("get Weather false:"+errorMessage);
                }
            });
        });

        globalViewModel.getTodoSyncAble().observe(this, new Observer<Boolean>() {
            @Override
            public void onChanged(Boolean aBoolean) {
                if(aBoolean)
                    todoSyncServiceManager.start();
                else
                    todoSyncServiceManager.stop();
            }
        });

        globalViewModel.getTriggerScreen().observe(this, new Observer<Boolean>() {
            @Override
            public void onChanged(Boolean aBoolean) {
                setUpProximityService();
            }
        });
    }


    private void closeAllConfigFragment(){
        getSupportFragmentManager().popBackStack();
    }

    //将该Activity上的触碰事件交给GestureDetector处理
    @Override
    public boolean onTouchEvent(MotionEvent me) {
        if (globalViewModel.isAppConfig())
            return true;

        boolean res = scaleGestureDetector.onTouchEvent(me);
        if (!scaleGestureDetector.isInProgress()) {
            res = detector.onTouchEvent(me);
        }
        return res;
    }


    @Override
    public void onDestroy() {
        //Log.i(TAG, "onDestroy....");
        super.onDestroy();
        if (clockStateMachine != null)
            clockStateMachine.destory();
        try {
            if (model.isTriggerScreen())
                stopService(proximityServiceIntent);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (backGroundAnimator != null)
            backGroundAnimator.stop();
    }


    @TargetApi(Build.VERSION_CODES.KITKAT)
    @Override
    protected void onResume() {
        //Log.i(TAG, "onDestroy....");
        super.onResume();
        getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
        if (!isPowerManagerDisable())
            wakeLock.acquire();
        if (backGroundAnimator != null)
            backGroundAnimator.start();
        clockStateMachine.start();
    }

    @Override
    protected void onStart() {
        super.onStart();
        if(model.isFirstStart())
            firstStartSetup();
    }

    @Override
    protected void onPause() {
        super.onPause();
        //timber.log.Timber.d("onPause..");
        if (!isPowerManagerDisable())
            wakeLock.release();
        if (backGroundAnimator != null)
            backGroundAnimator.stop();
        clockStateMachine.stop();
    }

    public void configBackGroundImage() {
        PictureSelector.create(MainActivity.this)
                .openGallery(PictureMimeType.ofImage())
                .isCamera(false)
                .imageSpanCount(4)
                .forResult(PictureConfig.CHOOSE_REQUEST);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) {
            List<LocalMedia> selectList;
            switch (requestCode) {
                case PictureConfig.CHOOSE_REQUEST:
                    // 图片、视频、音频选择结果回调
                    selectList = PictureSelector.obtainMultipleResult(data);
                    // 例如 LocalMedia 里面返回三种path
                    // 1.media.getPath(); 为原图path
                    // 2.media.getCutPath();为裁剪后path，需判断media.isCut();是否为true  注意：音视频除外
                    // 3.media.getCompressPath();为压缩后path，需判断media.isCompressed();是否为true  注意：音视频除外
                    // 如果裁剪并压缩了，以取压缩路径为准，因为是先裁剪后压缩的

                    globalViewModel.setBackgroundImageUri(Uri.parse(selectList.get(0).getPath()));
                    globalViewModel.setBackgroundImageVisable(true);
                    break;
                case PictureConfig.TYPE_VIDEO:
                    selectList = PictureSelector.obtainMultipleResult(data);
                    model.setTimeHourVideoPath(selectList.get(0).getPath());
                    break;
            }
        }
    }

    protected void setBackGroundColor(Integer color) {
        if (null == color)
            return;
        themeUIContainer.setBackgroundColor(color);
    }

    public void nextBackGroundAnimator() {
        boolean randomColor = globalViewModel.getBackgroundAnimatorRandomColor();
        if (!randomColor && backGroundAnimator != null) {
            globalViewModel.setBackgroundAnimatorRandomColor(true);
            backGroundAnimator.setRandColor(true);
            animatorView.setAnimator(backGroundAnimator);
        } else {
            globalViewModel.setBackgroundAnimatorRandomColor(false);
            globalViewModel.setBackgroundAnimatorName(animatorManager.next());
        }
    }

    public void changeBackGroundAnimator(String animatorName, boolean randomColor) {
        backGroundAnimator = animatorManager.configByName(animatorName);
        if (backGroundAnimator != null) {
            backGroundAnimator.init(animatorView.getContext(), animatorView);
            backGroundAnimator.setRandColor(randomColor);
        }
        animatorView.setAnimator(backGroundAnimator);
    }

    public void changeBackGroudAnimatorColor(int color) {
        animatorView.setColor(color);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (isScreenLock())
            return super.onKeyDown(keyCode, event);
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            if (globalViewModel.isAppConfig()) {
                getSupportFragmentManager().popBackStack();
                getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
                return true;
            }
            if (!isFullScreen()) {
                DialogUtils.show(this,"温馨提示","确定要退出吗",ok->{
                    if(ok){
                        MainActivity.this.finish();
                    }
                });
            }
            getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
            return true;
        } else if (keyCode == KeyEvent.KEYCODE_MENU) {
            setup();
        }
        return super.onKeyDown(keyCode, event);
    }

    public void setup() {
        getSupportFragmentManager().beginTransaction().replace(R.id.fragment_config_container, new SystemAppConfigFragment()).addToBackStack(null).commit();
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
    }

    @Override
    public void onPointerCaptureChanged(boolean hasCapture) {

    }

    private boolean isScreenLock() {
        return globalViewModel.getSrceenLock().getValue();
    }

    private boolean isScreenLockWithPassword(){
        return isScreenLock()&&globalViewModel.getScreenLockPassword()>0;
    }

    private boolean isFullScreen() {
        return themeUIViewModel.getClockUITypeEnum().getValue() == FULLSCREEN;
    }

    @Override
    public boolean onDown(MotionEvent motionEvent) {
        return false;
    }

    @Override
    public void onShowPress(MotionEvent motionEvent) {
    }

    @Override
    public boolean onSingleTapUp(MotionEvent motionEvent) {
        return false;
    }

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        return false;
    }

    @Override
    public void onLongPress(MotionEvent motionEvent) {
        if(isScreenLockWithPassword())
            return ;
        showConfigThemeUI();
    }

    private void showConfigThemeUI() {
        if (globalViewModel.getClockModeEnum().getValue() != ClockModeEnum.NORMAL)
            return;
        switch (globalViewModel.getClockInterfaceTypeEnum().getValue()) {
            case Digit:
                getSupportFragmentManager().beginTransaction().replace(R.id.fragment_config_container, new DigitClockConfigFragment()).addToBackStack(null).commit();
                break;
            case Simulate:
                getSupportFragmentManager().beginTransaction().replace(R.id.fragment_config_container, new SimulateClockConfigFragment()).addToBackStack(null).commit();
                break;
        }
    }

    private void changeThemeUI() {
        //if (!isPowerManagerDisable())
        //    localWakeLock.isHeld();
        switch (globalViewModel.getClockInterfaceTypeEnum().getValue()) {
            case Digit:
                if (getCurrentThemeMode() == FULLSCREEN)
                    switchMode(ClockThemeUITypeEnum.NORMAL);
                else if (getCurrentThemeMode() == SETTING)
                    switchMode(ClockThemeUITypeEnum.FULLSCREEN);
                else
                    switchMode(SETTING);
                break;
            case Simulate:
                if (getCurrentThemeMode() == SETTING)
                    switchMode(FULLSCREEN);
                else
                    switchMode(SETTING);
                break;
        }
    }


    private void switchMode(ClockThemeUITypeEnum uiTypeEnum) {
        themeUIViewModel.setClockUITypeEnum(uiTypeEnum);
    }

    private ClockThemeUITypeEnum getCurrentThemeMode() {
        return themeUIViewModel.getClockUITypeEnum().getValue();
    }

    Integer flingWidth;
    Integer flingHeight;

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float v, float v1) {
        if (isScreenLock() && !isFullScreen())
            return true;

        if(isScreenLockWithPassword())
            return true;

        timber.log.Timber.d("onFling");

        int brightness = globalViewModel.getBrightness().getValue();

        if(flingWidth==null)
            calcFilingFlag();

        if (e2.getY() - e1.getY() < -flingHeight) {         // 从上至下
            timber.log.Timber.d("change brightness +10");
            brightness = brightness + 10;
            if (brightness >= 255) {
                Toast.makeText(this, "最大亮度了", Toast.LENGTH_SHORT).show();
                return true;
            }
            globalViewModel.getBrightness().setValue(brightness);
            return true;
        } else if (e2.getY() - e1.getY() > flingHeight) {         // 从下至上
            timber.log.Timber.d("change brightness -10");
            brightness = brightness - 10;
            if (brightness <= 0) {
                Toast.makeText(this, "最小亮度了", Toast.LENGTH_SHORT).show();
                return true;
            }
            globalViewModel.getBrightness().setValue(brightness);
            return true;
        } else if (e2.getX() - e1.getX() > flingWidth) {             // 从左向右滑动（左进右出）
            timber.log.Timber.d("left->right");
            if (globalViewModel.getClockInterfaceTypeEnum().getValue() == ClockInterfaceTypeEnum.Simulate) {
                simulateViewModel.setClockTypeName(ClockFactory.nextSimulateClockName(simulateViewModel.getClockTypeName().getValue()));
                return true;
            }
            digitViewModel.setTimeFontStyle(fontManager.nextFont());
            return true;
        } else if (e2.getX() - e1.getX() < -flingWidth) {         // 从右向左滑动（右进左出）
            nextBackGroundAnimator();
            return true;
        }
        return false;
    }


    @Override
    public boolean onSingleTapConfirmed(MotionEvent e) {
        clockStateMachine.uiClockChecked();
        return true;
    }


    @Override
    public boolean onDoubleTap(MotionEvent e) {
        changeThemeUI();
        return true;
    }

    @Override
    public boolean onDoubleTapEvent(MotionEvent e) {
        return false;
    }



    float scaleSpan = 0;
    int currentFontSize;
    //int maxFontSize;
    @Override
    public boolean onScaleBegin(ScaleGestureDetector detector) {
        if(isScreenLockWithPassword())
            return false;
        timber.log.Timber.d("onScaleBegin ");
        scaleSpan = detector.getCurrentSpan();
        currentFontSize=digitViewModel.getTimeFontStyleSize().getValue();
        //maxFontSize = fontManager.getMaxFontSize(model.isDisplaySecond());
        return true;
    }

    @Override
    public boolean onScale(ScaleGestureDetector detector) {

        float span = detector.getCurrentSpan() - scaleSpan;
        int step = new Float(span / 30).intValue();

        currentFontSize = currentFontSize + step;

        timber.log.Timber.d("onScaleEnd span:" + span + "\t step:" + step + "\tcurrent text size" + currentFontSize);

        digitViewModel.setTimeFontStyleSize(currentFontSize);

        return false;
    }

    @Override
    public void onScaleEnd(ScaleGestureDetector detector) {
        fontManager.updateCurrentFontSize(isFullScreen(), model.isDisplaySecond(), currentFontSize);
    }


    /**
     * 改变App当前Window亮度
     *
     * @param brightness
     */
    public void changeAppBrightness(int brightness) {
        Window window = this.getWindow();
        WindowManager.LayoutParams lp = window.getAttributes();
        if (brightness == -1) {
            lp.screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE;
        } else {
            lp.screenBrightness = (brightness <= 0 ? 1 : brightness) / 255f;
        }
        window.setAttributes(lp);
        //Toast.makeText(this,"当前亮度："+getnum(brightness,255),Toast.LENGTH_SHORT).show();
    }

    private int getSystemBrightness() {
        int systemBrightness = 0;
        try {
            systemBrightness = Settings.System.getInt(getContentResolver(), Settings.System.SCREEN_BRIGHTNESS);
        } catch (Settings.SettingNotFoundException e) {
            e.printStackTrace();
        }
        return systemBrightness;
    }

    public String getnum(int num1, int num2) {
        NumberFormat numberFormat = NumberFormat.getInstance();
        // 设置精确到小数点后0位
        numberFormat.setMaximumFractionDigits(0);
        String result = numberFormat.format((float) num1 / (float) num2 * 100);
        return result + "%";
    }

    public ClockStateMachine getClockStateMachine() {
        return clockStateMachine;
    }


    public AlterManager getAlterManager() {
        return alterManager;
    }

    public TodoSyncServiceManager getTodoSyncServiceManager() {
        return todoSyncServiceManager;
    }

    private void calcFilingFlag() {
        Point outSize=new Point();
        WindowManager windowManager = getWindowManager();
        Display display = windowManager.getDefaultDisplay();
        display.getSize(outSize);
        flingWidth=outSize.x/3;
        flingHeight =outSize.y/3;
        //timber.log.Timber.d("calc filing flag flingWidth:"+flingWidth+"\tflingHeight"+flingHeight);
    }

    @Override
    public void exit() {

    }
}
